El rendimiento académico es un tema clave en la educación, ya que influye directamente en las oportunidades que tendrán los jovenes en el día de mañana y en el desarrollo de nuestra sociedad. Comprender qué factores afectan al desempeño de los estudiantes permitirá a las instituciones educativas a mejorar los métodos de enseñanza, diseñar políticas educativas más efectivas y proporcionar un mayor apoyo a aquellos estudiantes que lo necesiten.
Este estudio analiza los factores que influyen en el rendimiento académico de los estudiantes. Para ello, se hace uso de datos relacionados con aspectos personales, sociales y académicos para identificar patrones y determinar qué variables tienen mayor impacto en el desempeño escolar.
En particular, el estudio se enfoca en responder dos preguntas fundamentales:
¿Se pueden agrupar a los estudiantes en una clase según
sus características?
La organización de los estudiantes dentro del aula puede influir
significativamente en su aprendizaje y rendimiento. Por esta razón, se
explorará la posibilidad de segmentar a los alumnos con base en
características clave como sus calificaciones previas, el tiempo
dedicado al estudio, su nivel de motivación, la presencia de
discapacidades de aprendizaje y su participación en actividades
extracurriculares.
Este enfoque permitirá una distribución estratégica que potencie el aprendizaje al ubicar a los estudiantes en entornos que favorezcan su desarrollo académico y personal.
¿Cuántas horas de trabajo personal necesita un estudiante
para obtener una alta calificación?
Otro objetivo del estudio es determinar cuántas horas diarias de estudio
autónomo son necesarias para que un estudiante alcance una calificación
alta (entre 8 y 10). Para ello, se analizarán factores como las horas de
estudio semanal, el tiempo de sueño diario y la cantidad de sesiones de
tutoría recibidas, ya que estos aspectos pueden influir en el
rendimiento académico. A través de un modelo de regresión, se buscará
cuantificar la relación entre estas variables y el desempeño
estudiantil, proporcionando una guía para optimizar los hábitos de
estudio.
A través de este análisis, se pretende aportar información valiosa para mejorar las estrategias educativas, optimizar la distribución de los estudiantes en el aula y ofrecer recomendaciones que permitan a los alumnos maximizar su rendimiento académico.
El mundo en el que vivimos está en constante transformación. Los sistemas educativos, como muchos otros aspectos de nuestra sociedad, deben adaptarse a nuevas realidades y desafíos. En este contexto, resulta crucial comprender los factores que influyen en el rendimiento académico de los estudiantes, con el objetivo de mejorar los procesos de enseñanza y crear un entorno de aprendizaje más inclusivo y eficaz. Lo interesante de este estudio radica en identificar patrones y relaciones entre distintas variables que podrían tener un impacto directo en la forma en que los estudiantes aprenden y se desarrollan.
En particular, nos gustaría subrayar que el rendimiento académico no depende únicamente de la capacidad intelectual del estudiante, sino también de factores como el apoyo familiar, los hábitos de estudio, la motivación personal y la presencia de discapacidades de aprendizaje. Este enfoque permite adoptar una perspectiva más personalizada de la educación, lo que a su vez puede contribuir a una mejor planificación y diseño de estrategias pedagógicas más adaptadas a las necesidades de los estudiantes.
En el grupo de desarrollo de este trabajo, nos encontramos tanto estudiantes de Ingeniería Informática como de Ingeniería de la Salud. Esta diversidad de perspectivas y formaciones académicas enriquece el enfoque del estudio, ya que, desde distintas disciplinas, reconocemos la importancia de crear un entorno educativo que no solo se base en el rendimiento académico, sino también en el bienestar y las capacidades individuales de cada estudiante. Al ser nosotros mismos estudiantes, sabemos de primera mano que las aulas son cada vez más diversas, y entender cómo organizar y distribuir a los estudiantes de acuerdo con sus necesidades específicas es clave para optimizar su rendimiento.
A nivel global, la educación es un pilar fundamental para el desarrollo. Países con bajos índices de rendimiento académico suelen enfrentar mayores desafíos económicos y sociales. Además, en un contexto postpandemia, donde la enseñanza a distancia ha cambiado la forma en que los estudiantes aprenden, es más importante que nunca entender qué factores afectan su desempeño y cómo pueden optimizarse los procesos de enseñanza.
El dataset ha sido extraído de la plataforma Kaggle y proporcionado por el usuario lainguyn123. Se puede acceder al conjunto de datos a través del siguiente enlace: Student Performance Factors Dataset.
El archivo que contiene el conjunto de datos se denomina StudentPerformanceFactors y está en formato CSV, con un tamaño aproximado de 641 kB.
Este conjunto de datos proviene de una investigación que analiza los factores que afectan el rendimiento académico de los estudiantes. Incluye diversas variables relacionadas con características personales, académicas y sociales, tales como hábitos de estudio, asistencia, participación de los padres, y otros aspectos clave que influyen en el éxito académico de los estudiantes.
En cuanto a sus dimensiones, el dataset consta de un total de:
6,607 Filas
20 Columnas
La función ipak está diseñada para facilitar la instalación y carga de paquetes en R. Es útil cuando desea asegurarse de que todos los paquetes necesarios para un script o proyecto se instalan y cargan automáticamente. https://gist.github.com/stevenworthington/3178163
ipak <- function(pkg){
new.pkg <- pkg[!(pkg %in% installed.packages()[, "Package"])]
if(length(new.pkg))
install.packages(new.pkg, dependencies = TRUE)
sapply(pkg, require, character.only = TRUE)
}
packages <- c("tidyverse","ggplot2", "dplyr","gridExtra", "reshape2")
ipak(packages)
tidyverse ggplot2 dplyr gridExtra reshape2
TRUE TRUE TRUE TRUE TRUE
data <- read.csv("data/StudentPerformanceFactors.csv", header=TRUE)
head(data)
str(data)
'data.frame': 6607 obs. of 20 variables:
$ Hours_Studied : int 23 19 24 29 19 19 29 25 17 23 ...
$ Attendance : int 84 64 98 89 92 88 84 78 94 98 ...
$ Parental_Involvement : chr "Low" "Low" "Medium" "Low" ...
$ Access_to_Resources : chr "High" "Medium" "Medium" "Medium" ...
$ Extracurricular_Activities: chr "No" "No" "Yes" "Yes" ...
$ Sleep_Hours : int 7 8 7 8 6 8 7 6 6 8 ...
$ Previous_Scores : int 73 59 91 98 65 89 68 50 80 71 ...
$ Motivation_Level : chr "Low" "Low" "Medium" "Medium" ...
$ Internet_Access : chr "Yes" "Yes" "Yes" "Yes" ...
$ Tutoring_Sessions : int 0 2 2 1 3 3 1 1 0 0 ...
$ Family_Income : chr "Low" "Medium" "Medium" "Medium" ...
$ Teacher_Quality : chr "Medium" "Medium" "Medium" "Medium" ...
$ School_Type : chr "Public" "Public" "Public" "Public" ...
$ Peer_Influence : chr "Positive" "Negative" "Neutral" "Negative" ...
$ Physical_Activity : int 3 4 4 4 4 3 2 2 1 5 ...
$ Learning_Disabilities : chr "No" "No" "No" "No" ...
$ Parental_Education_Level : chr "High School" "College" "Postgraduate" "High School" ...
$ Distance_from_Home : chr "Near" "Moderate" "Near" "Moderate" ...
$ Gender : chr "Male" "Female" "Male" "Male" ...
$ Exam_Score : int 67 61 74 71 70 71 67 66 69 72 ...
El dataset está compuesto por 6,607 filas y 20 columnas, las cuales incluyen atributos de distintos tipos: numéricos, categóricos y booleanos.
A continuación, se describen algunos de estos atributos:
Hours_Studied: Número de horas de estudio semanales.
Attendance: Porcentaje de clases a las que ha asistido.
Parental_Involvement: Nivel de implicación de los padres en la educación del alumno (Low, Medium, High).
Access_to_Resources: Disponibilidad de recursos educativos (Low, Medium, High).
Extracurricular_Activities: Participación en actividades extraescolares (Yes, No).
Sleep_Hours: Número medio de horas de sueño por noche.
Previous_Scores: Puntuaciones de exámenes anteriores.
Motivation_Level: Nivel de motivación del estudiante (Low, Medium, High).
Internet_Access: Disponibilidad de acceso a Internet (Yes, No).
Tutoring_Sessions: Número de sesiones de tutoría a las que asiste al mes.
Family_Income: Nivel de ingresos familiares (Low, Medium, High).
Teacher_Quality: Calidad de los profesores (Low, Medium, High).
School_Type: Tipo de escuela a la que asistió (Public, Private).
Peer_Influence: Influencia de los compañeros en el rendimiento académico (Positive, Neutral, Negative).
Physical_Activity: Número medio de horas de actividad física a la semana.
Learning_Disabilities: Presencia de dificultades de aprendizaje (Yes, No).
Parental_Education_Level: Nivel educativo más alto de los padres (High School, College, Postgraduate).
Distance_from_Home: Distancia de casa a la escuela (Near, Moderate, Far).
Gender: Género del estudiante (Male, Female).
Exam_Score: Calificación del examen final.
ggplot(df_cleaned, aes(x = Hours_Studied)) +
geom_histogram(binwidth = 1,
fill = "cornflowerblue", color = "black", bins = 20) +
labs(title = "Studied Hours analysis", x = "Hours Studied", y = "Count") +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5))
ggplot(df_cleaned, aes(x = Sleep_Hours)) +
geom_histogram(binwidth = 1,
fill = "cornflowerblue", color = "black", bins = 20) +
labs(title = "Sleep Hours Analysis", x = "Sleep Hours", y = "Count") +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5))
ggplot(df_cleaned, aes(x = Tutoring_Sessions)) +
geom_histogram(binwidth = 1,
fill = "cornflowerblue", color = "black", bins = 20) +
labs(title = "Tutoring Sessions Analysis", x = "Tutoring Sessions", y = "Count") +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5))
ggplot(df_cleaned, aes(x = Attendance)) +
geom_histogram(binwidth = 5,
fill = "cornflowerblue", color = "black", bins = 20) +
labs(title = "Attendance Analysis", x = "Attendance(%)", y = "Count") +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5))
ggplot(data, aes(x = Previous_Scores)) +
geom_histogram(binwidth = 1, fill = "orange", color = "black") +
labs(title = "Distribution of Previous Scores", x = "Previous Scores", y = "Count")
ggplot(data, aes(x = Exam_Score)) +
geom_histogram(binwidth = 1, fill = "cornflowerblue", color = "black") +
labs(title = "Distribution of Exam Scores", x = "Exam Score", y = "Count")
create_pie_chart <- function(df, var_name) {
if (!(var_name %in% colnames(df))) {
stop("La variable no existe en el dataframe.")
}
dist_var <- as.data.frame(table(df[[var_name]]))
colnames(dist_var) <- c(var_name, "Count")
dist_var$Percentage <- round(dist_var$Count / sum(dist_var$Count) * 100, 1)
ggplot(dist_var, aes(x = "", y = Count, fill = get(var_name))) +
geom_bar(stat = "identity", width = 1) +
coord_polar(theta = "y") +
geom_text(aes(label = paste0(Percentage, "%")), position = position_stack(vjust = 0.5), size = 5) +
labs(title = paste("Distribución de", var_name), fill=var_name) +
theme_minimal() +
theme(axis.text.x = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank())
}
create_pie_chart(data, "Parental_Involvement")
create_pie_chart(data, "Access_to_Resources")
create_pie_chart(data, "Parental_Education_Level")
create_pie_chart(data, "Distance_from_Home")
create_pie_chart(data, "Extracurricular_Activities")
create_pie_chart(data, "School_Type")
create_pie_chart(data, "Gender")
Esta función muestra las filas con valores NA o valores vacios(““).
detect_missing_data <- function(df) {
na_count <- colSums(is.na(df)) # Contar los NA en cada columna
empty_count <- colSums(sapply(df, function(x) x == "")) # Contar los valores vacíos en cada columna
missing_data <- data.frame(NA_Count = na_count, Empty_Count = empty_count)
missing_data <- missing_data[missing_data$NA_Count > 0 | missing_data$Empty_Count > 0, ]
return(missing_data)
}
missing_data <- detect_missing_data(data)
missing_data
En el resultado arrojado por la función podemos observar que no existen valores NA en las columnas de nuestro dataframe, lo que significa que no hay datos explícitamente faltantes o nulos. Sin embargo, también notamos que hay filas con valores vacíos en ciertas variables categóricas.
Al sumar el total de valores faltantes podemos observar que puede haber un máximo de 235 filas con algún valor faltante. Esto supone aproximadamente el 3.56% del total de filas del conjunto de datos.
Dado que la proporción de filas con valores faltantes es relativamente baja, consideramos eliminar estas instancias ya que creemos que no tendrá un impacto significativo en la integridad general del dataset.
clean_missing_data <- function(df) {
original_row_count <- nrow(df)
df <- df[!apply(df, 1, function(x) any(is.na(x) | x == "")), ] #Borramos las filas
cleaned_row_count <- nrow(df)
rows_removed <- original_row_count - cleaned_row_count
cat("Número de filas eliminadas:", rows_removed, "\n")
return(df)
}
data <- clean_missing_data(data)
Número de filas eliminadas: 229
Observamos que se han eliminado 229 filas por lo que el dataset sin ningún valor de faltante constaría de un total de 6378 filas.
Para preparar los datos de manera óptima para el análisis, aplicamos varias transformaciones a las variables categóricas y ordinales. Esto nos permite estructurar la información de manera que los modelos puedan interpretarla correctamente.
Con esta función convertimos las columnas del data frame en factores ordenados y les asignamos valores enteros, de acuerdo con un orden específico de niveles. Esto es util para las variables que tienen una relación de orden o tienen un nivel jerárquico o progresivo, es decir, que pueden compararse en términos de más o menos, mejor o peor, mayor o menor.
Parental_Involvement,Access_to_Resources,Motivation_Level,Family_Income,Teacher_Quality
Estas variables pueden ordenarse de menor a mayor o
viceversa”..
En Peer_Influence, Positive > Neutral
> Negative en términos de impacto en el rendimiento. Por lo
que tambien se pueden ordenar.
En Distance_from_Home ordenamos los valores en
términos de nivel de cercanía de la escuela a la casa
del estudiante.
En Parental_Education_Level ordenamos los valores en
términos de nivel de estudio de los padres. Desde menos
estudios (High School) hasta más estudios (Postgraduate).
convert_to_ordered_int <- function(df, column_names, levels_order, ordered = TRUE) {
for (col in column_names) {
if (col %in% colnames(df)) {
df[[col]] <- as.integer(factor(df[[col]], levels = levels_order, ordered = ordered))
}
}
return(df)
}
Algunas variables categóricas contienen únicamente valores “Yes” o “No”, por lo que es más eficiente transformarlas en valores 0 y 1, ‘No’ y ‘Yes’, respectivamente.
Las variables modificadas serán:
Extracurricular_Activities,
Internet_Access, Learning_Disabilities → Yes =
1, No = 0convert_to_binary <- function(df, column_names) {
for (col in column_names) {
if (col %in% colnames(df)) {
df[[col]] <- ifelse(df[[col]] == "Yes", 1, 0)
}
}
return(df)
}
Algunas variables no tienen una jerarquía clara, por lo que en lugar de asignar valores ordinales, creamos columnas binarias (dummies) para cada categoría, es decir, aplicamos One-Hot Encoding.
School_Type pasará a dividirse en dos columnas:
School_Type_Public y School_Type_PrivateGender se convierte en Gender_Male y
Gender_Female.convert_to_one_hot <- function(df, column_names) {
for (col in column_names) {
if (col %in% colnames(df)) {
unique_values <- unique(df[[col]])
for (val in unique_values) {
new_col_name <- paste(col, val, sep = "_")
df[[new_col_name]] <- ifelse(df[[col]] == val, 1, 0)
}
df[[col]] <- NULL # Eliminamos la columna original después de crear las dummy variables
}
}
return(df)
}
clean_and_filter_data <- function(data) {
data <- data %>%
distinct() %>%
# Convertir a valores ordenados (Low < Medium < High)
convert_to_ordered_int(c("Parental_Involvement", "Access_to_Resources", "Motivation_Level",
"Family_Income", "Teacher_Quality"),
c("Low", "Medium", "High")) %>%
# Convertir Peer_Influence en valores ordenados (Negative < Neutral < Positive)
convert_to_ordered_int("Peer_Influence", c("Negative", "Neutral", "Positive")) %>%
# Convertir Parental Education Level en valores ordenados (High School < College < Postgraduate)
convert_to_ordered_int("Parental_Education_Level", c("High School", "College", "Postgraduate")) %>%
# Convertir Distance_from_Home en valores ordenados (Near < Moderate < Far)
convert_to_ordered_int("Distance_from_Home", c("Near", "Moderate", "Far")) %>%
# Convertir a valores binarios (No = 0, Yes = 1)
mutate(
Extracurricular_Activities = ifelse(Extracurricular_Activities == "Yes", 1, 0),
Internet_Access = ifelse(Internet_Access == "Yes", 1, 0),
Learning_Disabilities = ifelse(Learning_Disabilities == "Yes", 1, 0)
) %>%
# Aplicar One-Hot Encoding a School_Type y Gender
mutate(
School_Type_Private = ifelse(School_Type == "Private", 1, 0),
School_Type_Public = ifelse(School_Type == "Public", 1, 0),
Gender_Male = ifelse(Gender == "Male", 1, 0),
Gender_Female = ifelse(Gender == "Female", 1, 0)
) %>%
# Eliminar las columnas originales después de One-Hot Encoding
select(-School_Type, -Gender)
return(data)
}
df_cleaned <- clean_and_filter_data(data)
df_cleaned
Después de la codificación, nuestro dataset consta de estos tipos:
str(df_cleaned)
'data.frame': 6378 obs. of 22 variables:
$ Hours_Studied : int 23 19 24 29 19 19 29 25 17 23 ...
$ Attendance : int 84 64 98 89 92 88 84 78 94 98 ...
$ Parental_Involvement : int 1 1 2 1 2 2 2 1 2 2 ...
$ Access_to_Resources : int 3 2 2 2 2 2 1 3 3 2 ...
$ Extracurricular_Activities: num 0 0 1 1 1 1 1 1 0 1 ...
$ Sleep_Hours : int 7 8 7 8 6 8 7 6 6 8 ...
$ Previous_Scores : int 73 59 91 98 65 89 68 50 80 71 ...
$ Motivation_Level : int 1 1 2 2 2 2 1 2 3 2 ...
$ Internet_Access : num 1 1 1 1 1 1 1 1 1 1 ...
$ Tutoring_Sessions : int 0 2 2 1 3 3 1 1 0 0 ...
$ Family_Income : int 1 2 2 2 2 2 1 3 2 3 ...
$ Teacher_Quality : int 2 2 2 2 3 2 2 3 1 3 ...
$ Peer_Influence : int 3 1 2 1 2 3 2 1 2 3 ...
$ Physical_Activity : int 3 4 4 4 4 3 2 2 1 5 ...
$ Learning_Disabilities : num 0 0 0 0 0 0 0 0 0 0 ...
$ Parental_Education_Level : int 1 2 3 1 2 3 1 1 2 1 ...
$ Distance_from_Home : int 1 2 1 2 1 1 2 3 1 2 ...
$ Exam_Score : int 67 61 74 71 70 71 67 66 69 72 ...
$ School_Type_Private : num 0 0 0 0 0 0 1 0 1 0 ...
$ School_Type_Public : num 1 1 1 1 1 1 0 1 0 1 ...
$ Gender_Male : num 1 0 1 1 0 1 1 1 1 1 ...
$ Gender_Female : num 0 1 0 0 1 0 0 0 0 0 ...
Para que el análisis sea óptimo, también es necesario escalar las variables.
Sleep_Hours toma como valor las horas de sueño por
noche y será modificado ma horas semanales.Tutoring_Sessions toma como valor las sesiones de
tutoria por mes. Para escalar esta variable, se tomará 1 sesión de
tutoría = 30 minutos (0.5 horas) y a su vez, se pasará a horas
semanales. Por ejemplo, si un estudiante tiene
Tutoring_Sessions = 4 en un mes, significa 4 * 0.5 = 2
horas/mes, y seguidamente lo pasaremos a horas semanales, es decir,
(Tutoring_Sessions*0.5)/4.
scale_time_variables <- function(df) {
df <- df %>%
mutate(
Sleep_Hours = Sleep_Hours * 7, # Convertir de horas por noche a horas por semana
Tutoring_Sessions = (Tutoring_Sessions * 0.5) / 4 # Convertir sesiones a horas/semana
)
return(df)
}
df_cleaned <- scale_time_variables(df_cleaned)
print("Sleep_Hours:")
[1] "Sleep_Hours:"
summary(df_cleaned$Sleep_Hours) # Debería estar en un rango de 0-56 horas semanales
Min. 1st Qu. Median Mean 3rd Qu. Max.
28.00 42.00 49.00 49.24 56.00 70.00
print("Tutoring_Sessions:")
[1] "Tutoring_Sessions:"
summary(df_cleaned$Tutoring_Sessions) # Ahora representará horas de tutoría por semana
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.1250 0.1250 0.1869 0.2500 1.0000
Como puede observarse, para las horas de sueño semanales, el mínimo es 28, lo cual significa que hay estudiantes que duermen 4 horas por noche (4 * 7 = 28). La mediana es 49, lo que indica que la mayoría de los estudiantes duermen aproximadamente 7 horas por noche (7 * 7 = 49). El máximo es 70, lo que implica que algunos estudiantes duermen 10 horas por noche (10 * 7 = 70).
Por otro lado, para las horas de tutoría por semana, el mínimo es 0, lo cual es correcto, ya que algunos estudiantes no tienen sesiones de tutoría. La mediana es 0.125, lo que significa que muchos estudiantes tienen 0.5 sesiones por mes (0.5 * 0.5 / 4 = 0.125 horas/semana). El máximo es 1, lo que indica que algunos estudiantes tienen 4 sesiones de tutoría por mes, que equivale a 1 hora de tutoría por semana (4 * 0.5 / 4 = 1).
data_notas_altas <- df_cleaned[df_cleaned$Previous_Scores >= 80,]
data_notas_altas
data_numeric <- data_notas_altas[, sapply(data_notas_altas, is.numeric)]
data_scaled <- as.data.frame(scale(data_numeric))
data_notas_altas[, sapply(data_notas_altas, is.numeric)] <- data_scaled
data_notas_altas
matriz_correlacion <- cor(data_notas_altas)
matriz_correlacion
Hours_Studied Attendance Parental_Involvement Access_to_Resources Extracurricular_Activities Sleep_Hours Previous_Scores Motivation_Level
Hours_Studied 1.0000000000 0.0057353760 -0.008706360 -0.0145032184 -9.083585e-03 0.030085928 0.0181605349 -0.031250699
Attendance 0.0057353760 1.0000000000 0.005487197 0.0018296144 5.178361e-03 -0.028814705 0.0181104928 -0.025395481
Parental_Involvement -0.0087063598 0.0054871972 1.000000000 -0.0414333665 -3.993572e-03 -0.003527708 -0.0371816335 -0.025427649
Access_to_Resources -0.0145032184 0.0018296144 -0.041433366 1.0000000000 -2.208387e-02 0.003106121 -0.0002459505 0.019477001
Extracurricular_Activities -0.0090835852 0.0051783611 -0.003993572 -0.0220838721 1.000000e+00 0.024115356 0.0034000720 0.015060092
Sleep_Hours 0.0300859285 -0.0288147050 -0.003527708 0.0031061208 2.411536e-02 1.000000000 0.0066212959 -0.009059232
Previous_Scores 0.0181605349 0.0181104928 -0.037181634 -0.0002459505 3.400072e-03 0.006621296 1.0000000000 -0.008703580
Motivation_Level -0.0312506987 -0.0253954809 -0.025427649 0.0194770008 1.506009e-02 -0.009059232 -0.0087035795 1.000000000
Internet_Access 0.0390459105 -0.0397097112 0.040999007 -0.0204034588 -7.895317e-05 0.013306069 -0.0051156735 0.014003823
Tutoring_Sessions -0.0139626887 0.0132780048 -0.012808659 -0.0155179375 1.280105e-02 -0.017232208 -0.0021058662 0.017306236
Family_Income 0.0098326736 -0.0008342265 0.027209257 0.0296735645 -1.148151e-02 -0.015409148 -0.0106144989 0.007950042
Teacher_Quality 0.0007257928 -0.0448063864 0.030391526 -0.0129246345 1.285137e-02 0.026420210 -0.0111261222 0.007931348
Peer_Influence 0.0259876188 -0.0303958476 0.012369207 0.0082753292 1.914012e-02 0.004469257 -0.0114926016 -0.006098864
Physical_Activity -0.0101587727 -0.0177957945 -0.021571495 -0.0190732959 1.358148e-02 -0.021824931 0.0094163600 0.006200311
Learning_Disabilities -0.0030028683 -0.0180733462 0.026024819 -0.0018443126 -1.339738e-02 -0.009766882 -0.0267885313 -0.020263795
Parental_Education_Level -0.0132016742 0.0465009924 -0.027847002 -0.0027754401 -6.423198e-03 -0.005028627 -0.0089829682 0.010950264
Distance_from_Home 0.0004332880 -0.0054979637 -0.003346233 -0.0170027123 2.997926e-02 -0.011729066 0.0111284594 -0.028715277
Exam_Score 0.4606397857 0.5893764043 0.163645905 0.1698461318 6.937706e-02 -0.007232403 0.1001096910 0.061051452
School_Type_Private 0.0197293920 0.0151055526 -0.002017221 0.0134709041 -1.819009e-02 0.032535635 -0.0040933482 -0.022917618
School_Type_Public -0.0197293920 -0.0151055526 0.002017221 -0.0134709041 1.819009e-02 -0.032535635 0.0040933482 0.022917618
Gender_Male -0.0157232829 0.0238838814 -0.037066121 -0.0109547041 1.434582e-02 -0.009216923 0.0038395286 0.032999233
Gender_Female 0.0157232829 -0.0238838814 0.037066121 0.0109547041 -1.434582e-02 0.009216923 -0.0038395286 -0.032999233
Internet_Access Tutoring_Sessions Family_Income Teacher_Quality Peer_Influence Physical_Activity Learning_Disabilities
Hours_Studied 3.904591e-02 -0.013962689 0.0098326736 0.0007257928 0.025987619 -0.0101587727 -0.003002868
Attendance -3.970971e-02 0.013278005 -0.0008342265 -0.0448063864 -0.030395848 -0.0177957945 -0.018073346
Parental_Involvement 4.099901e-02 -0.012808659 0.0272092574 0.0303915263 0.012369207 -0.0215714949 0.026024819
Access_to_Resources -2.040346e-02 -0.015517938 0.0296735645 -0.0129246345 0.008275329 -0.0190732959 -0.001844313
Extracurricular_Activities -7.895317e-05 0.012801052 -0.0114815094 0.0128513738 0.019140125 0.0135814780 -0.013397376
Sleep_Hours 1.330607e-02 -0.017232208 -0.0154091478 0.0264202101 0.004469257 -0.0218249308 -0.009766882
Previous_Scores -5.115673e-03 -0.002105866 -0.0106144989 -0.0111261222 -0.011492602 0.0094163600 -0.026788531
Motivation_Level 1.400382e-02 0.017306236 0.0079500423 0.0079313479 -0.006098864 0.0062003108 -0.020263795
Internet_Access 1.000000e+00 -0.009467260 0.0286751985 0.0046641865 -0.008097068 -0.0255024796 0.009956722
Tutoring_Sessions -9.467260e-03 1.000000000 -0.0232031925 -0.0027424101 -0.019599613 0.0142919289 0.027568097
Family_Income 2.867520e-02 -0.023203193 1.0000000000 -0.0015286010 0.027915177 -0.0369761496 0.006915153
Teacher_Quality 4.664186e-03 -0.002742410 -0.0015286010 1.0000000000 0.015062485 -0.0222783154 0.029515252
Peer_Influence -8.097068e-03 -0.019599613 0.0279151770 0.0150624849 1.000000000 0.0023681522 -0.016708988
Physical_Activity -2.550248e-02 0.014291929 -0.0369761496 -0.0222783154 0.002368152 1.0000000000 0.000309724
Learning_Disabilities 9.956722e-03 0.027568097 0.0069151530 0.0295152519 -0.016708988 0.0003097240 1.000000000
Parental_Education_Level -3.201538e-03 -0.001533609 -0.0021971371 0.0078578141 0.020007218 -0.0162017930 -0.019962871
Distance_from_Home -1.622058e-02 -0.016185780 -0.0310730803 0.0109615772 0.010502027 -0.0233456199 -0.007397311
Exam_Score 5.822807e-02 0.148566931 0.1061028815 0.0587247150 0.106822057 0.0251852361 -0.087380464
School_Type_Private -5.104194e-03 0.012423234 -0.0268550484 0.0034700881 -0.023044078 0.0150268480 -0.006196310
School_Type_Public 5.104194e-03 -0.012423234 0.0268550484 -0.0034700881 0.023044078 -0.0150268480 0.006196310
Gender_Male 4.366866e-02 -0.003584893 0.0122293916 -0.0362211569 -0.020231529 -0.0004055917 0.008938475
Gender_Female -4.366866e-02 0.003584893 -0.0122293916 0.0362211569 0.020231529 0.0004055917 -0.008938475
Parental_Education_Level Distance_from_Home Exam_Score School_Type_Private School_Type_Public Gender_Male Gender_Female
Hours_Studied -0.013201674 0.000433288 0.460639786 0.0197293920 -0.0197293920 -0.0157232829 0.0157232829
Attendance 0.046500992 -0.005497964 0.589376404 0.0151055526 -0.0151055526 0.0238838814 -0.0238838814
Parental_Involvement -0.027847002 -0.003346233 0.163645905 -0.0020172212 0.0020172212 -0.0370661207 0.0370661207
Access_to_Resources -0.002775440 -0.017002712 0.169846132 0.0134709041 -0.0134709041 -0.0109547041 0.0109547041
Extracurricular_Activities -0.006423198 0.029979258 0.069377065 -0.0181900936 0.0181900936 0.0143458216 -0.0143458216
Sleep_Hours -0.005028627 -0.011729066 -0.007232403 0.0325356347 -0.0325356347 -0.0092169233 0.0092169233
Previous_Scores -0.008982968 0.011128459 0.100109691 -0.0040933482 0.0040933482 0.0038395286 -0.0038395286
Motivation_Level 0.010950264 -0.028715277 0.061051452 -0.0229176181 0.0229176181 0.0329992329 -0.0329992329
Internet_Access -0.003201538 -0.016220585 0.058228066 -0.0051041936 0.0051041936 0.0436686589 -0.0436686589
Tutoring_Sessions -0.001533609 -0.016185780 0.148566931 0.0124232336 -0.0124232336 -0.0035848927 0.0035848927
Family_Income -0.002197137 -0.031073080 0.106102881 -0.0268550484 0.0268550484 0.0122293916 -0.0122293916
Teacher_Quality 0.007857814 0.010961577 0.058724715 0.0034700881 -0.0034700881 -0.0362211569 0.0362211569
Peer_Influence 0.020007218 0.010502027 0.106822057 -0.0230440782 0.0230440782 -0.0202315292 0.0202315292
Physical_Activity -0.016201793 -0.023345620 0.025185236 0.0150268480 -0.0150268480 -0.0004055917 0.0004055917
Learning_Disabilities -0.019962871 -0.007397311 -0.087380464 -0.0061963103 0.0061963103 0.0089384750 -0.0089384750
Parental_Education_Level 1.000000000 0.011776083 0.120495892 0.0215753304 -0.0215753304 -0.0081061368 0.0081061368
Distance_from_Home 0.011776083 1.000000000 -0.086711632 -0.0280159559 0.0280159559 -0.0193370059 0.0193370059
Exam_Score 0.120495892 -0.086711632 1.000000000 0.0190029766 -0.0190029766 -0.0147877366 0.0147877366
School_Type_Private 0.021575330 -0.028015956 0.019002977 1.0000000000 -1.0000000000 -0.0005145086 0.0005145086
School_Type_Public -0.021575330 0.028015956 -0.019002977 -1.0000000000 1.0000000000 0.0005145086 -0.0005145086
Gender_Male -0.008106137 -0.019337006 -0.014787737 -0.0005145086 0.0005145086 1.0000000000 -1.0000000000
Gender_Female 0.008106137 0.019337006 0.014787737 0.0005145086 -0.0005145086 -1.0000000000 1.0000000000
# Convierte la matriz en un dataframe largo (long format)
matriz_melt <- melt(matriz_correlacion)
# Genera el mapa de calor
ggplot(data = matriz_melt, aes(Var1, Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-1, 1), space = "Lab",
name = "Correlación") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
labs(x = "Variables", y = "Variables", title = "Mapa de Calor de Correlación")
col_names <- colnames(data_notas_altas)
col_names <- col_names[!is.na(col_names)] # Eliminar posibles NA en nombres de columnas
# Asegurarse de que Previous_Scores no tenga valores faltantes
data_notas_altas <- data_notas_altas[!is.na(data_notas_altas$Previous_Scores) & is.finite(data_notas_altas$Previous_Scores), ]
# Convertir variables ordinales o categóricas en factores
data_notas_altas$Distance_from_Home <- factor(
data_notas_altas$Distance_from_Home,
levels = c(1, 2, 3),
labels = c("Near", "Moderate", "Far")
)
# Lista para almacenar los valores numéricos de las interacciones
interaction_data <- list()
for (i in 1:(length(col_names)-1)) { # Ajustar el límite superior
for (j in (i+1):length(col_names)) {
name1 <- col_names[i]
name2 <- col_names[j]
# Verificar que las variables sean adecuadas para el gráfico
if (!is.na(name1) && !is.na(name2) && name1 != "Previous_Scores" && name2 != "Previous_Scores") {
# Convertir las variables a factores si no lo son
if (!is.factor(data_notas_altas[[name1]]) && !is.numeric(data_notas_altas[[name1]])) {
data_notas_altas[[name1]] <- as.factor(data_notas_altas[[name1]])
}
if (!is.factor(data_notas_altas[[name2]]) && !is.numeric(data_notas_altas[[name2]])) {
data_notas_altas[[name2]] <- as.factor(data_notas_altas[[name2]])
}
# Calcular los promedios por nivel de interacción
interaction_values <- tapply(
data_notas_altas$Previous_Scores,
list(data_notas_altas[[name1]], data_notas_altas[[name2]]),
mean,
na.rm = TRUE
)
# Guardar los valores en la lista
interaction_data[[paste(name1, name2, sep = "_vs_")]] <- interaction_values
# Generar el gráfico de interacción
interaction.plot(
x.factor = data_notas_altas[[name1]],
trace.factor = data_notas_altas[[name2]],
response = data_notas_altas$Previous_Scores,
xlab = name1,
ylab = "Previous Scores",
main = paste("Interacción:", name1, "vs", name2),
ylim = range(data_notas_altas$Previous_Scores, na.rm = TRUE) # Establecer límites
)
}
}
}
# Guardar los valores numéricos en un archivo para uso posterior
save(interaction_data, file = "interaction_data.RData")